package com.sync.data.common.statusmachine;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @author liquanchang
 */
public class StatusDefinition {

    public static List<StatusDefinition> statusDefinitions = new ArrayList<>();

//    // 在静态块中初始化
//    static {
//        // 会议对象状态定义
//        statusDefinitions.add(new StatusDefinition("MtEvent","draft","pending,approved,execution",true,true));
//        statusDefinitions.add(new StatusDefinition("MtEvent","pending","approved",true,false));
//        statusDefinitions.add(new StatusDefinition("MtEvent","approved","execution,draft",true,false));
//        statusDefinitions.add(new StatusDefinition("MtEvent","execution","waiting",true,false));
//        statusDefinitions.add(new StatusDefinition("MtEvent","waiting","completed",true,false));
//        statusDefinitions.add(new StatusDefinition("MtEvent","completed",null,false,false));
//    }

    public String object;

    public String recordType;

    public String status;

    public String nextStatus;

    public boolean control;

    public boolean isFirst;

    public StatusDefinition(String object, String status, String nextStatus, boolean control, boolean isFirst) {
        this.object = object;
        this.status = status;
        this.nextStatus = nextStatus;
        this.control = control;
        this.isFirst = isFirst;
    }

    public StatusDefinition(String object, String recordType, String status, String nextStatus, boolean control, boolean isFirst) {
        this.object = object;
        this.recordType = recordType;
        this.status = status;
        this.nextStatus = nextStatus;
        this.control = control;
        this.isFirst = isFirst;
    }

    /**
     * 状态校验
     * @param currentStatus 当前要变化到的状态
     * @param previousStatus 变化之前的老状态
     * @param object 对象
     */
    public static void verifyStatus(String currentStatus,
                                    String previousStatus,
                                    String object){

        verifyStatus(currentStatus,previousStatus,object,null);

    }

    /**
     * 状态校验
     * @param currentStatus 当前要变化到的状态
     * @param previousStatus 变化之前的老状态
     * @param object 对象
     * @param recordType 类型
     */
    public static void verifyStatus(String currentStatus,
                                    String previousStatus,
                                    String object,
                                    String recordType){

        Assert.notNull(currentStatus,"目标状态不能为空");

        // 获取新状态定义
        StatusDefinition currentStatusDefinition = null;

        if(StrUtil.isEmpty(recordType)){
            currentStatusDefinition = statusDefinitions.stream().filter(a -> object.equals(a.object) && currentStatus.equals(a.status)).findAny().orElse(null);
        }else {
            currentStatusDefinition = statusDefinitions.stream().filter(a -> object.equals(a.object) && currentStatus.equals(a.status) && recordType.equals(a.recordType)).findAny().orElse(null);
        }

        Assert.notNull(currentStatusDefinition,object+"对象未定义"+currentStatus+"状态");

        // 任意状态可进入节点
        if(!currentStatusDefinition.control){
            return;
        }

        // 老状态为空
        if(StrUtil.isEmpty(previousStatus)){
            Assert.isTrue(currentStatusDefinition.isFirst,"目标状态非初始状态");
            return;
        }

        // 获取老状态定义
        StatusDefinition previousStatusDefinition = null;

        if(StrUtil.isEmpty(recordType)){
            previousStatusDefinition = statusDefinitions.stream().filter(a -> object.equals(a.object) && previousStatus.equals(a.status)).findAny().orElse(null);
        }else {
            previousStatusDefinition = statusDefinitions.stream().filter(a -> object.equals(a.object) && previousStatus.equals(a.status) && recordType.equals(a.recordType)).findAny().orElse(null);
        }

        Assert.notNull(previousStatusDefinition,object+"对象未定义"+previousStatus+"状态");

        Assert.notNull(previousStatusDefinition.nextStatus,"当前状态已终止，不可变更");

        if(currentStatus.equals(previousStatus)){
            return;
        }

        String[] nextStatusArr = previousStatusDefinition.nextStatus.split(",");

        boolean nextStatusEnable = false;

        for(String nextStatus : nextStatusArr){
            if(currentStatus.equals(nextStatus)){
                nextStatusEnable = true;
                break;
            }
        }

        Assert.isTrue(nextStatusEnable,"目标状态"+currentStatus+"不符合定义，对象"+object+"的"+previousStatus+"状态的next状态只能为"+previousStatusDefinition.nextStatus);
    }

}
